package com.yupi.longojcodesandbox.utils;

import cn.hutool.core.util.StrUtil;
import com.yupi.longojcodesandbox.model.ExecuteMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;

import java.io.*;
import java.util.ArrayList;

/*
* 进程工具类
* */
public class ProcessUtils {

    /**
     * 执行进程并获取信息
     * @param runProcess
     * @param opName
     * @return
     */
        public static ExecuteMessage runProcessAndGetMessage(Process runProcess,String opName){

            ExecuteMessage executeMessage = new ExecuteMessage();

            try {
                StopWatch stopWatch = new StopWatch();
                stopWatch.start();
                //等待程序执行，获取错误码
                int exitValue = runProcess.waitFor();
                executeMessage.setExitValue(exitValue);
                //正常退出
                if (exitValue==0){
                    System.out.println(opName+"成功");
                    //分批获取进程的正常输出
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                    ArrayList<String> outputStrList = new ArrayList<>();
                    //逐行读取
                    String compileOutputLine ;
                    while ((compileOutputLine = bufferedReader.readLine())!=null){
                            outputStrList.add(compileOutputLine);
                    }
                    executeMessage.setMessage(StringUtils.join(outputStrList,"\n"));
                } else {
                    //异常退出
                    System.out.println(opName+"失败，错误码：" + exitValue);
                    //分批获取进程的输出
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                    ArrayList<String> outputStrList = new ArrayList<>();
                    //逐行读取
                    String compileOutputLine ;
                    while ((compileOutputLine = bufferedReader.readLine())!=null){
                        outputStrList.add(compileOutputLine);
                    }
                    executeMessage.setMessage(StringUtils.join(outputStrList,"\n"));
                    //分批获取进程的失败输出
                    BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
                    ArrayList<String> errorOutputStrList = new ArrayList<>();
                    //逐行读取
                    String errorCompileOutputLine ;
                    while ((errorCompileOutputLine = errorBufferedReader.readLine())!=null){
                       errorOutputStrList.add(errorCompileOutputLine);
                    }
                   executeMessage.setErrorMessage(StringUtils.join(errorOutputStrList,"\n"));
                }
                stopWatch.stop();
                executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
            } catch (IOException | InterruptedException e) {
                throw new RuntimeException(e);
            }

            return executeMessage;

        }

    /**
     * 执行交互式进程
      * @param runProcess
     * @param opName
     * @return
     */
        public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess,String opName,String args){
            ExecuteMessage executeMessage = new ExecuteMessage();

            try {
                //向控制台输入程序
                OutputStream outputStream = runProcess.getOutputStream();
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
                String[] s = args.split(" ");
                String join = StrUtil.join("\n", s) + "\n";
                outputStreamWriter.write(join);
                //相当于回车，执行输入的发送
                outputStreamWriter.flush();
                //分批获取进程的正常输出
                InputStream inputStream = runProcess.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    ArrayList<String> outputStrList = new ArrayList<>();
                    //逐行读取
                    String compileOutputLine ;
                    while ((compileOutputLine = bufferedReader.readLine())!=null){
                        outputStrList.add(compileOutputLine);
                    }
                    executeMessage.setMessage(StringUtils.join(outputStrList,"\n"));
                    //记得关闭流，释放资源，否则可能会卡死
                outputStreamWriter.close();
                outputStream.close();
                inputStream.close();
                runProcess.destroy();
                } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return executeMessage;
        }
}
